package com.molichuxing.gateway.bff.dealer.services.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateTypeUtil;
import com.molichuxing.framework.utils.RedisUtil;
import com.molichuxing.gateway.bff.dealer.convertor.Convert;
import com.molichuxing.gateway.bff.dealer.entity.request.modify.create.StoreCreateVo;
import com.molichuxing.gateway.bff.dealer.entity.response.StoreInfoVo;
import com.molichuxing.gateway.bff.dealer.entity.response.StoreModifyStatusVo;
import com.molichuxing.gateway.bff.dealer.entity.response.StoreModifyVo;
import com.molichuxing.gateway.bff.dealer.entity.response.StoreVo;
import com.molichuxing.gateway.bff.dealer.services.StoreBffService;
import com.molichuxing.gateway.property.StoreStatusAndVerifyEnum;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.services.business.dto.request.create.StockBizCreateDto;
import com.molichuxing.services.business.dto.request.create.StoreBizCreateDto;
import com.molichuxing.services.business.dto.request.modify.StockBizModifyDto;
import com.molichuxing.services.business.dto.request.modify.StoreBizModifyDto;
import com.molichuxing.services.business.dto.response.StoreBizDto;
import com.molichuxing.services.business.dto.response.StoreInfoBizDto;
import com.molichuxing.services.business.service.StockStoreBizService;
import com.molichuxing.services.business.service.StoreBizService;
import com.molichuxing.services.infrastructure.dto.request.create.IovFenceCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.IovFenceModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.StoreDetailModifyDto;
import com.molichuxing.services.infrastructure.dto.response.RegionInfoDto;
import com.molichuxing.services.infrastructure.dto.response.StoreDetailDto;
import com.molichuxing.services.infrastructure.dto.response.StoreDto;
import com.molichuxing.services.infrastructure.dto.response.VehicleMakeDto;
import com.molichuxing.services.infrastructure.service.IovFenceService;
import com.molichuxing.services.infrastructure.service.RegionService;
import com.molichuxing.services.infrastructure.service.StoreDetailService;
import com.molichuxing.services.infrastructure.service.StoreService;
import com.molichuxing.services.infrastructure.service.VehicleMakeService;
import com.molichuxing.services.property.IovFenceAlarmTypeEnum;
import com.molichuxing.services.property.IovFenceShapeEnum;
import com.molichuxing.services.property.StoreStatusEnum;
import com.molichuxing.services.property.StoreStatusModifyTypeEnum;
import com.molichuxing.services.property.StoreVerifyStatusEnum;

@Service("storeBffService")
public class StoreBffServiceImpl implements StoreBffService {
    private static final Logger logger = LoggerFactory.getLogger(StoreBffServiceImpl.class);

    @Resource
	private RedisUtil redisUtil;

    @Resource
    private StoreService storeService;

    @Resource
    private RegionService regionService;

    @Resource
    private StoreBizService storeBizService;

    @Resource
    private StockStoreBizService stockStoreBizService;

    @Resource
    private VehicleMakeService vehicleMakeService;

    @Resource
    private StoreDetailService storeDetailService;

    @Resource
    private IovFenceService iovFenceService;

    @Value("${store.fence.width}")
    private String STORE_FENCE_WIDTH;

    /**
     * 获取门店信息
     *
     * @param dealerId 经销商id
     * @return
     */
    @Override
    public List<StoreVo> getStoreByDealerId(Integer dealerId) {
        List<StoreVo> result = null;
        // redis中获取
		// String redisKey = RedisKeyConst.DEALER_STORE_DEALER + dealerId;
		// String stores = redisUtil.get(redisKey);
		// if (StringUtils.isNotBlank(stores)) {
		// // 存在
		// return JSONObject.parseObject(stores, List.class);
		// }
        // 根据经销商id查询门店id
        List<StoreDto> storeDtos = storeService.getByDealer(dealerId);
        if (storeDtos == null || storeDtos.isEmpty()) {
            return result;
        }
        result = Convert.toStoreVo(storeDtos);
        // 存入redis
		// redisUtil.set(redisKey, JSONObject.toJSONString(result));
        return result;
    }

    /**
     * 获取门店营业中信息
     *
     * @param dealerId       经销商id
     * @param notShowStoreId 不显示门店id
     * @return
     */
    @Override
    public List<StoreVo> getOpenStoreByDealerId(Integer dealerId, Integer notShowStoreId) {
        // 根据经销商id查询门店id
        List<StoreDto> storeDtos = storeService.getStoreByDealer(dealerId);
        List<StoreVo> storeVos = Convert.toStoreVo(storeDtos);

        if (null == notShowStoreId) {
            return storeVos;
        }

        if (null == storeVos || storeVos.size() < 1) {
            return storeVos;
        }
        for (StoreVo storeVo : storeVos) {
            Integer storeId = storeVo.getStoreId();
            if (null == storeId) {
                continue;
            }
            if (storeId.equals(notShowStoreId)) {
                storeVos.remove(storeVo);
                break;
            }
        }

        return storeVos;
    }

    /**
     * 门店分页列表
     *
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     * @throws Exception
     */
    @Override
    public Paged<StoreVo> getStorePage(Map<String, Object> params, Integer pageNum, Integer pageSize) throws Exception {
        Integer dealerId = RequestAttrUtil.getCurrentDealerId();
        params.put("dealerId", dealerId);
        Paged<StoreBizDto> storePage = storeBizService.getStorePage(params, pageNum, pageSize);
        List<StoreBizDto> storeBizDtoList = storePage.getList();
        if (null == storeBizDtoList) {
            Paged<StoreVo> paged = new Paged<StoreVo>();
            return getPageTab(paged, dealerId);
        }

        List<Integer> regionIdList = new ArrayList<>();
        for (StoreBizDto storeBizDto : storeBizDtoList) {
            Integer regionId = storeBizDto.getRegionId();
            regionIdList.add(regionId);
        }

        Map<Integer, RegionInfoDto> regionInfoMap = regionService.getRegionInfoListByIds(regionIdList);
        List<StoreVo> storeVoList = Convert.toStoreVoList(storeBizDtoList, regionInfoMap);

        Paged<StoreVo> paged = new Paged<StoreVo>(storeVoList, storePage.getTotal(), pageSize);
        return getPageTab(paged, dealerId);
    }

    /**
     * 获取分页tab值
     *
     * @return
     * @throws Exception
     */
    private Paged<StoreVo> getPageTab(Paged<StoreVo> paged, Integer dealerId) throws Exception {

        Map<Integer, Integer> statusCountMap = storeService.getStoreCountByStatus(dealerId);
        Map<Integer, Integer> verifyStatusCountMap = storeService.getStoreCountByVerifyStatus(dealerId);
        Integer allCount = storeService.getCount(dealerId);

        List<TabDto> tabList = new ArrayList<>();
        for (StoreStatusAndVerifyEnum storeStatusAndVerifyEnum : StoreStatusAndVerifyEnum.values()) {
            int value = storeStatusAndVerifyEnum.getValue();
            String name = storeStatusAndVerifyEnum.getName();

            Integer count = 0;
            if (StoreStatusAndVerifyEnum.ALL.getValue() == value) {
                count = allCount;
            } else if (StoreStatusAndVerifyEnum.UN_VERIFY.getValue() == value
                    && null != verifyStatusCountMap
                    && verifyStatusCountMap.size() > 0) {
                count = verifyStatusCountMap.get(StoreVerifyStatusEnum.UN_VERIFY.getValue());
            } else if (StoreStatusAndVerifyEnum.VERIFY_REJECT.getValue() == value
                    && null != verifyStatusCountMap
                    && verifyStatusCountMap.size() > 0) {
                count = verifyStatusCountMap.get(StoreVerifyStatusEnum.VERIFY_REJECT.getValue());
            } else if (StoreStatusAndVerifyEnum.OPEN.getValue() == value
                    && null != statusCountMap
                    && statusCountMap.size() > 0) {
                count = statusCountMap.get(StoreStatusEnum.OPEN.getValue());
            } else if (StoreStatusAndVerifyEnum.SUSPENSION.getValue() == value
                    && null != statusCountMap
                    && statusCountMap.size() > 0) {
                count = statusCountMap.get(StoreStatusEnum.SUSPENSION.getValue());
            }

            if (null == count) {
                count = 0;
            }

            TabDto tabDto = new TabDto();
            tabDto.setName(name);
            tabDto.setType(value);
            tabDto.setCount(count);
            tabList.add(tabDto);
        }
        return paged.setTab(tabList);
    }


    /**
     * 编辑门店
     *
     * @param storeModifyVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyStore(StoreModifyVo storeModifyVo) throws Exception {
        StoreBizModifyDto storeBizModifyDto = Convert.toStoreBizModifyDto(storeModifyVo);
        Boolean aBoolean = storeBizService.modifyStore(storeBizModifyDto);
        if (!aBoolean) {
            return false;
        }

        StockBizModifyDto stockBizModifyDto = Convert.toStockBizModifyDto(storeModifyVo);
        return stockStoreBizService.modify(stockBizModifyDto);
    }

    /**
     * 编辑门店营业状态
     *
     * @param storeModifyStatusVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyStoreStatus(StoreModifyStatusVo storeModifyStatusVo) throws Exception {
        Integer storeId = storeModifyStatusVo.getStoreId();
        Integer status = storeModifyStatusVo.getStatus();

        return storeBizService.modifyStoreStatus(storeId, status, StoreStatusModifyTypeEnum.DEALER.getValue());
    }

    /**
     * 新增门店
     *
     * @param storeCreateVo
     * @return
     * @throws Exception
     */
    @Override
    public Boolean createStore(StoreCreateVo storeCreateVo) throws Exception {

        StoreBizCreateDto storeBizCreateDto = Convert.toStoreBizCreateDto(storeCreateVo);
        Integer storeId = storeBizService.createStore(storeBizCreateDto);
        if (null == storeId) {
            return false;
        }

        StockBizCreateDto stockBizCreateDto = Convert.toStockBizCreateDto(storeCreateVo);
        stockBizCreateDto.setStoreId(storeId);
        return stockStoreBizService.create(stockBizCreateDto);
    }

    /**
     * 门店审核
     *
     * @param storeId
     * @param verifyStatus
     * @param rejectReason
     * @param remark
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyStoreVerifyStatus(Integer storeId, Integer verifyStatus, String rejectReason, String remark) throws Exception {
        Assert.notNull(storeId, "门店审核失败");
        Assert.notNull(verifyStatus, "门店审核失败");

        StoreDto storeDto = storeService.getStoreById(storeId);
        Assert.notNull(storeDto, "门店不存在");

        Integer oldFenceId = null;
        Integer fenceId = null;
        if (StoreVerifyStatusEnum.VERIFY_PASS.getValue() == verifyStatus) {
            StoreDetailDto storeDetailDto = storeDetailService.getStoreDetailById(storeId);
            oldFenceId = storeDetailDto.getFenceId();
            fenceId = addOrModifyFence(storeDto, storeDetailDto);
        }

        Boolean modifyStoreBoolean = storeBizService.modifyStoreVerifyStatus(storeId, verifyStatus, rejectReason, remark);
        if (!modifyStoreBoolean && StoreVerifyStatusEnum.VERIFY_PASS.getValue() == verifyStatus && null == oldFenceId && fenceId != null) {
            daletefence(fenceId);
        }
        return modifyStoreBoolean;
    }

    /**
     * 添加修改围栏
     *
     * @param storeDto
     * @param storeDetailDto
     * @return
     * @throws Exception
     */
    private Integer addOrModifyFence(StoreDto storeDto, StoreDetailDto storeDetailDto) throws Exception {
        Integer oldFenceId = storeDetailDto.getFenceId();
        if (null == oldFenceId) {
            Integer fenceId = addfence(storeDto, storeDetailDto);
            if (null == fenceId) {
                throw new BizException("车联网创建围栏失败");
            }
            StoreDetailModifyDto storeDetailModifyDto = new StoreDetailModifyDto();
            storeDetailModifyDto.setStoreId(storeDto.getStoreId());
            storeDetailModifyDto.setFenceId(fenceId);
            Boolean modifyStoreBoolean = storeDetailService.modifyStoreDetail(storeDetailModifyDto);
            if (!modifyStoreBoolean) {
                daletefence(fenceId);
            }
            return fenceId;
        } else {
            Boolean modifyFenceBoolean = modifyFence(storeDto, storeDetailDto);
            if (!modifyFenceBoolean) {
                throw new BizException("车联网编辑围栏失败");
            }
            return oldFenceId;
        }
    }


    /**
     * 添加围栏
     *
     * @param storeDto
     * @param storeDetailDto
     * @return
     * @throws Exception
     */
    private Integer addfence(StoreDto storeDto, StoreDetailDto storeDetailDto) throws Exception {
        String shortName = storeDto.getShortName();
        String address = storeDetailDto.getAddress();
        Integer regionId = storeDto.getRegionId();
        String longitude = storeDetailDto.getLongitude();
        String dimension = storeDetailDto.getDimension();

        String regionAddress = getRegionAddress(regionId);
        if (StringUtils.isNotBlank(regionAddress)) {
            address = regionAddress + address;
        }

        IovFenceCreateDto iovFenceCreateDto = new IovFenceCreateDto();
        iovFenceCreateDto.setFenceName(shortName);
        iovFenceCreateDto.setFenceArea(address);
        iovFenceCreateDto.setAlarmType(IovFenceAlarmTypeEnum.OUT.getValue());
        iovFenceCreateDto.setFenceShape(IovFenceShapeEnum.CIRCLE.getValue());
        iovFenceCreateDto.setRadius(DateTypeUtil.strCastDouble(STORE_FENCE_WIDTH));
        iovFenceCreateDto.setLatitude(DateTypeUtil.strCastDouble(dimension));
        iovFenceCreateDto.setLongitude(DateTypeUtil.strCastDouble(longitude));
        return iovFenceService.addFence(iovFenceCreateDto);
    }


    /**
     * 修改围栏
     *
     * @param storeDto
     * @param storeDetailDto
     * @return
     * @throws Exception
     */
    private Boolean modifyFence(StoreDto storeDto, StoreDetailDto storeDetailDto) throws Exception {
        String shortName = storeDto.getShortName();
        String address = storeDetailDto.getAddress();
        Integer regionId = storeDto.getRegionId();
        String longitude = storeDetailDto.getLongitude();
        String dimension = storeDetailDto.getDimension();

        String regionAddress = getRegionAddress(regionId);
        if (StringUtils.isNotBlank(regionAddress)) {
            address = regionAddress + address;
        }
        Integer fenceId = storeDetailDto.getFenceId();

        IovFenceModifyDto iovFenceDto = new IovFenceModifyDto();
        iovFenceDto.setId(DateTypeUtil.integerCastLong(fenceId));
        iovFenceDto.setFenceName(shortName);
        iovFenceDto.setFenceArea(address);
        iovFenceDto.setAlarmType(IovFenceAlarmTypeEnum.OUT.getValue());
        iovFenceDto.setFenceShape(IovFenceShapeEnum.CIRCLE.getValue());
        iovFenceDto.setRadius(DateTypeUtil.strCastDouble(STORE_FENCE_WIDTH));
        iovFenceDto.setLatitude(DateTypeUtil.strCastDouble(dimension));
        iovFenceDto.setLongitude(DateTypeUtil.strCastDouble(longitude));
        return iovFenceService.modifyFence(iovFenceDto);
    }


    /**
     * 删除围栏
     *
     * @param fenceId
     * @return
     * @throws Exception
     */
    private Boolean daletefence(Integer fenceId) throws Exception {
        return iovFenceService.deleteFence(fenceId);
    }

    /**
     * 获取门店详情
     *
     * @param storeId
     * @return
     */
    @Override
    public StoreInfoVo getStoreInfo(Integer storeId) throws Exception {
        StoreInfoBizDto storeInfo = storeBizService.getStoreInfo(storeId);
        StoreInfoVo storeInfoVo = Convert.toStoreInfoVo(storeInfo);

        Integer brandId = storeInfo.getBrandId();
        Integer regionId = storeInfo.getRegionId();
        if (brandId != null) {
            VehicleMakeDto vehicleMakeDto = vehicleMakeService.getVehicleMakeDtoById(brandId);
            if (vehicleMakeDto != null) {
                storeInfoVo.setBrandName(vehicleMakeDto.getName());
            }
        }

        String regionAddress = getRegionAddress(regionId);
        if (StringUtils.isNotBlank(regionAddress)) {
            String address = storeInfoVo.getAddress();
            storeInfoVo.setDetailAddress(regionAddress + address);
        }

        RegionInfoDto regionInfoDto = regionService.getCityNameByCityId(regionId);
        if (regionInfoDto != null) {
            String provinceName = regionInfoDto.getProvinceFullName();
            String cityName = regionInfoDto.getCityFullName();
            Integer provinceId = regionInfoDto.getProvinceId();
            storeInfoVo.setProvinceId(provinceId);
            storeInfoVo.setProvinceName(provinceName);
            storeInfoVo.setCityName(cityName);
        }
        return storeInfoVo;
    }

    /**
     * 获取地址
     *
     * @param regionId
     * @return
     */
    private String getRegionAddress(Integer regionId) {
        String returnStr = "";
        if (null == regionId) {
            return "";
        }

        RegionInfoDto regionInfoDto = regionService.getCityNameByCityId(regionId);
        if (null == regionInfoDto) {
            return "";
        }

        String provinceName = regionInfoDto.getProvinceFullName();
        String cityName = regionInfoDto.getCityFullName();
        if (StringUtils.isNotBlank(provinceName)) {
            returnStr = returnStr + provinceName;
        }
        if (StringUtils.isNotBlank(cityName)) {
            returnStr = returnStr + cityName;
        }
        return returnStr;
    }


}
